<script setup>
import { computed, nextTick, onMounted, ref, watch } from "vue";
import useClipboard from "vue-clipboard3";
import { Plus, CopyDocument } from "@element-plus/icons-vue";
import { list, start, addChatMenu } from "../../services/chat";
import MarkdownIt from "markdown-it";
import "highlight.js/styles/base16/atelier-sulphurpool-light.css";
import { useChatMenuIdStore } from "../../store/ChatMenuStore";
import { ElMessage } from "element-plus";
import { bus } from "../../mitt/mitt";
const { toClipboard } = useClipboard();
//store
const chatMenuIdStore = useChatMenuIdStore();
//
const dialogVisible = ref(false);
const chatInfo = ref({
  question: "",
  chatMenuId: "",
  contentType: 0,
  prompt: "",
});
const chatId = ref();
const f_alConfig = function () {
  dialogVisible.value = true;
};
const chatContentList = ref([]);

//菜单id
const chatMenuId = computed(() => {
  return chatMenuIdStore.getChatMenuId;
});
const loading = ref(false);
//
const changeChatMenuId = ref("");
//监听菜单变化
watch(chatMenuId, (newVal, oldVal) => {
  if (changeChatMenuId.value == "") {
    getChatContentList(chatMenuId.value);
  }
  chatInfo.value.chatMenuId = chatMenuId.value;
});

//聊天内容
const markdown = new MarkdownIt();
const getChatContentList = function (id) {
  chatContentList.value = [];
  list(id)
    .then((res) => {
      res.data.forEach((i) => {
        i.realContent = i.replyContent;
        i.replyContent = markdown.render(i.replyContent);
      });
      chatContentList.value = res.data;
      scrollToBottom();
    })
    .catch((error) => {});
};

//头像
const userImg = computed(() => {
  return JSON.parse(localStorage.getItem("userData")).headPic;
});

//展示底部
const scrollContainer = ref(null);
const scrollToBottom = function () {
  nextTick(() => {
    scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight;
  });
};

//发送
const sendMsg = function () {
  if (chatInfo.value.question == "") {
    ElMessage.error("请输入提问内容");
    return;
  } else {
    if (chatInfo.value.chatMenuId == "") {
      addChatMenu({
        chatMenuName:
          chatInfo.value.question.length > 20
            ? chatInfo.value.question.substring(0, 20)
            : chatInfo.value.question,
      })
        .then((res) => {
          bus.emit("addChatMenu", "");
          nextTick(() => {
            chatInfo.value.chatMenuId = res.data;
            changeChatMenuId.value = res.data;
            sseWatch(res.data);
          });
        })
        .catch((error) => {});
    } else {
      sseWatch(chatInfo.value.chatMenuId);
    }
  }
};
// 复制到剪贴板
const _copy = (copyContent) => {
  try {
    toClipboard(copyContent);
    // 弹出复制成功信息
    ElMessage.success("复制成功");
  } catch (error) {
    console.log(error);
    // 弹出复制成功信息
    ElMessage.error("复制失败");
  }
};
//发送是否禁用
const isDisabled = ref(false);
//sse监听
const sseWatch = function (chatMenuId) {
  const id = Math.floor(Math.random() * 10000000) + "";
  chatId.value = id;
  const chatContent = ref({
    id: id,
    realContent: "",
    contentType: chatInfo.value.contentType,
    askContent: markdown.render(chatInfo.value.question),
    replyContent:
      (chatInfo.value.contentType == 1) | 2 ? "<br><br><br><br>" : "",
  });
  if (!!window.EventSource) {
    const chatUrl = import.meta.env.VITE_CHAT_SSE;
    var source = new EventSource(`${chatUrl}/addSse?id=${chatMenuId}`);
    source.onerror = (e) => {
      source.close();
      isDisabled.value = false;
      chatInfo.value.question = "";
    };
    //建立链接
    source.addEventListener("open", (e) => {});
    //监听开始消息
    source.addEventListener("start", (e) => {
      chatContentList.value.push(chatContent.value);
      loading.value = true;
      scrollToBottom();
      isDisabled.value = true;
      start(chatInfo.value)
        .then((res) => {})
        .catch((error) => {});
    });
    // 监听数据
    source.addEventListener("data", (e) => {
      loading.value = false;
      let sseData = JSON.parse(e.data);
      chatContent.value.realContent = sseData.text;
      chatContent.value.replyContent = markdown.render(sseData.text);
      scrollToBottom();
    });
    //监听后台err消息
    source.addEventListener("err", (e) => {
      loading.value = false;
      chatContent.value.realContent = e.data;
      chatContent.value.replyContent = markdown.render(e.data);
      scrollToBottom();
    });
  } else {
    console.log("你的浏览器不支持sse ");
  }
};

onMounted(() => {
  bus.on("delChatMenu", () => {
    chatContentList.value = [];
  });
});
</script>

<template>
  <el-card class="content-card">
    <div class="chat-top">
      <!-- <span style="font-size: 20px; color: #000">AI助手</span>
      &nbsp;
      <span>v1.0.0 |</span>
      &nbsp; -->
      <!-- <span style="font-size: 15px; color: #005320" @click="f_alConfig"
        >配置</span
      > -->
      <el-radio v-model="chatInfo.contentType" :label="0">通义千问</el-radio>
      <el-radio v-model="chatInfo.contentType" :label="1">通义万象</el-radio>
      <el-radio v-model="chatInfo.contentType" :label="2">创意字生成</el-radio>
      <span style="font-size: 15px; color: #005320" @click="f_alConfig"
        >配置</span
      >
    </div>
    <div class="chat-content" ref="scrollContainer">
      <div
        class="chat-content-item"
        v-for="item in chatContentList"
        :key="item.id"
      >
        <div class="ask">
          <el-avatar :size="30" style="margin-right: 10px">
            <img :src="userImg" />
          </el-avatar>
          <div class="ask-item" v-html="item.askContent"></div>
        </div>
        <div class="reply">
          <el-avatar :size="30" style="margin-right: 10px">
            <img src="../../assets/images/back.jpg" />
          </el-avatar>
          <div class="reply-item">
            <el-icon
              v-if="item.contentType == 0"
              size="20"
              class="copy-document"
              @click.stop="_copy(item.realContent)"
            >
              <CopyDocument />
            </el-icon>
            <div
              v-if="item.id == chatId"
              class="reply-item-item"
              v-html="item.replyContent"
              v-loading="loading"
              element-loading-text="加载中请稍等！！"
              v-highlight
            ></div>
            <div
              v-else
              class="reply-item-item"
              v-html="item.replyContent"
              v-highlight
            ></div>
          </div>
        </div>
      </div>
    </div>
    <div class="chat-content-input">
      <el-input
        v-model="chatInfo.question"
        type="textarea"
        :rows="4"
        placeholder="请输入内容"
        :disabled="isDisabled"
        @keydown.enter="sendMsg"
      ></el-input>
      <el-button
        style="height: 95px"
        type="primary"
        :icon="Plus"
        @click="sendMsg"
        :disabled="isDisabled"
        >发送
      </el-button>
    </div>
  </el-card>

  <el-dialog title="AI-配置" v-model="dialogVisible" width="400px">
    <div class="ai-config">
      <!-- <div>
        <el-radio v-model="chatInfo.contentType" :label="0">通义千问</el-radio>
        <el-radio v-model="chatInfo.contentType" :label="1">通义万象</el-radio>
      </div>
      <div v-if="chatInfo.contentType == 0">
        <el-radio v-model="chatInfo.model" label="qwen-v1">普通搜索</el-radio>
        <el-radio v-model="chatInfo.model" label="qwen-plus-v1"
          >增强搜索</el-radio
        >
      </div> -->
      <div>
        <el-form :model="chatInfo" ref="userFormRef" :rules="rules">
          <el-form-item label="创意样式提示词" prop="prompt">
            <el-input size="small" v-model="chatInfo.prompt"></el-input>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </el-dialog>
</template>

<style lang="less" scoped>
.content-card {
  height: 99%;

  .chat-top {
    height: 4vh;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}

.chat-content {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 2%;
  height: 73vh;

  .chat-content-item {
    .ask {
      margin-top: 15px;
      display: flex;
      justify-content: flex-end;

      /* 将内容靠右对齐 */
      .ask-item {
        line-height: 1.5;
        max-width: 30%;
        margin-right: 10px;
      }
    }

    .reply {
      margin-top: 15px;
      display: flex;

      .reply-item {
        background-color: #f3f3ff;
        width: 60%;
        border-radius: 10px;

        .reply-item-item {
          margin-left: 20px;
          margin-right: 20px;
          font-size: 15px;
          line-height: 1.5;
        }

        .copy-document {
          display: inline-block;
          float: right;
          margin: 5px 15px 0px 0px;
        }

        .copy-document :hover {
          cursor: pointer;
          color: rgb(57, 149, 255);
        }

        :deep(img) {
          max-width: 100%;
        }

        :deep(pre code.hljs) {
          margin-top: 10px;
          margin-bottom: 10px;
          border-radius: 10px;
        }
      }
    }
  }
}

.ai-config {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.chat-content-input {
  position: sticky;
  display: flex;
  bottom: 0;
  left: 0;
  width: 50%;
  margin-left: 25%;
  height: 100px;
}

:deep(.el-card__body) {
  padding: 0px;
}
</style>
